import express from 'express'

const app = express()

// CORS
app.use((req, res, next) => {
    console.log(new Date().toLocaleTimeString(), req.url.padEnd(10), req.headers.authorization)
    res.setHeader('Access-Control-Allow-Origin', '*')
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST')
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
    next()
})

// long aging time
let accessToken: string | null = null
// short aging time
let refreshToken: string | null = null

const ACCESS_EXPIRES = 5 * 1000
const REFRESH_EXPIRES = 10 * 1000

const uuid = () => Math.random().toString(16).slice(2) + '_' + Date.now()
const getAccessToken = (() => {
    let timer: NodeJS.Timeout | null = null
    return () => {
        if (timer) return accessToken
        accessToken = `accesstoken_${uuid()}`
        timer = setTimeout(() => {
            timer = null
            accessToken = null
        }, ACCESS_EXPIRES)
        return accessToken
    }
})()

const getRefreshToken = (() => {
    let timer: NodeJS.Timeout | null = null
    return () => {
        if (timer) return refreshToken
        refreshToken = `refreshtoken_${uuid()}`
        timer = setTimeout(() => {
            timer = null
            refreshToken = null
        }, REFRESH_EXPIRES)
        return refreshToken
    }
})()

// login
app.post('/login', (_, res) => {
    res.send({
        accessToken: getAccessToken(),
        refreshToken: getRefreshToken()
    })
})

// test
app.get('/test', (req, res) => {
    const params = new URL(req.url, `http://${req.headers.host}`).searchParams
    const _accessToken = req.headers.authorization
    if (_accessToken !== accessToken) {
        return res.status(401).json({
            error: 'Unauthorized AccessToken',
            i: params.get('i')
        })
    }
    res.send({
        name: 'test-' + params.get('i')
    })
})

app.get('/token', (req, res) => {
    const _refreshToken = req.headers.authorization
    // refreshToken 失效表示真的过期了，用户必须重新登录
    if (_refreshToken !== refreshToken) {
        return res.status(401).json({ error: 'Unauthorized RefreshToken' })
    }
    res.send({
        accessToken: getAccessToken()
    })
})

app.listen(8888, () => {
    console.log('App run: http://localhost:8888')
})